package com.lyf.boot.config;

import com.lyf.boot.callback.BootMqttCallBack;
import com.lyf.boot.properties.MqttProperties;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author Luyufan
 * @date 2023/7/10 16:00
 */
@Configuration
@RequiredArgsConstructor
@EnableConfigurationProperties(MqttProperties.class)
@ConditionalOnProperty(prefix = "mqtt", name = "enabled", havingValue = "true")
@Slf4j
public class MqttConfig {

    private final MqttProperties mqttProperties;

    @Bean
    public MqttClient mqttClient() throws MqttException {
        MqttClient mqttClient = new MqttClient(mqttProperties.getUrl(), mqttProperties.getClientId(), new MemoryPersistence());
        //连接设置
        MqttConnectOptions options = new MqttConnectOptions();
        //是否清空session，设置为false表示服务器会保留客户端的连接记录，客户端重连之后能获取到服务器在客户端断开连接期间推送的消息
        //设置为true表示每次连接到服务端都是以新的身份
        options.setCleanSession(true);
        //设置连接用户名
        options.setUserName(mqttProperties.getUsername());
        //设置连接密码
        options.setPassword(mqttProperties.getPassword().toCharArray());
        //设置超时时间，单位为秒
        options.setConnectionTimeout(100);
        //设置心跳时间 单位为秒，表示服务器每隔1.5*20秒的时间向客户端发送心跳判断客户端是否在线
        options.setKeepAliveInterval(20);
        //设置遗嘱消息的话题，若客户端和服务器之间的连接意外断开，服务器将发布客户端的遗嘱信息
        options.setWill("willTopic",(mqttProperties.getClientId() + "与服务器断开连接").getBytes(),0,false);
        //设置回调
        mqttClient.setCallback(new BootMqttCallBack(mqttProperties));
        mqttClient.connect(options);
        //订阅主题
        //消息等级，和主题数组一一对应，服务端将按照指定等级给订阅了主题的客户端推送消息
        int[] qos = {1, 1};
        //主题
        String[] topics = {"topic1", "topic2"};
        //订阅主题
        mqttClient.subscribe(topics,qos);
        log.debug("mqtt配置完成");
        return mqttClient;
    }

}
